const VueLoaderPlugin = require('vue-loader/lib/plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const webpack = require('webpack');
const path = require('path');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const globalConfig = require('./../config');

module.exports = function(calcConfig, alias = false) {
    const cssLoader = [ 'style-loader', MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader' ], 
        sassLoader = [ 'vue-style-loader', MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader', {
            loader: 'sass-resources-loader',
            options: {
                resources: [
                    path.join(calcConfig.srcPath, 'common/styles', '_variable.scss'),
                    path.join(calcConfig.srcPath, 'common/styles', '_mixins.scss'),
                    path.join(calcConfig.srcPath, 'common/styles', '_default.scss')
                ]
            }
        }],
        plugins = [ new VueLoaderPlugin() ],
        devMode = process.env.NODE_ENV === 'development',
        dllPath = path.join(calcConfig.basePath, 'dll', /*devMode ? 'vue_dll_dev' : */'vue_dll');

    if( devMode ) {
        cssLoader.splice(1, 1);
        sassLoader.splice(1, 1);
    } else {
        plugins.push(new webpack.DllReferencePlugin({
            context: dllPath,
            manifest: path.join(dllPath, 'vue.manifest.json')
        }));
    }
    
    plugins.push({
        apply: function(compiler) {
            compiler.hooks.emit.tapAsync('replaceModuleName', function(compilation, callback){
                compilation.chunks.forEach(chunk=>{
                    chunk.files.forEach(fileName=>{
                        let assets = compilation.assets,
                            asset = assets[ fileName ],
                            source = asset.source();
                        if( /\/hxswap\/%moduleName%\//.test(source) ) {
                            let newSource = source.replace(/(\/hxswap\/)(?:%(moduleName)%\/?)/i, (input, $0, $1) => {
                                let prefix = calcConfig[ $1 ];
                                if( alias ) prefix = globalConfig.prefix.moduleFix + prefix;
                                return $0 + prefix + '/';
                            });
                            assets[ fileName ] = Object.assign(asset, {
                                source: ()=>newSource,
                                size: ()=>Buffer.byteLength(newSource, 'utf-8')
                            });
                        }
                    });
                });
                callback();
            });
        }
    });

    return {
        module: {
            rules: [{
                test: /\.vue$/,
                loader: 'vue-loader',
                include: /src/,
                exclude: /node_modules/
            }, {
                test: /\.css$/,
                use: cssLoader
            }, {
                test: /\.scss$/,
                use: sassLoader
            },
            // {
            //   test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
            //   use: sassLoader
            // }
        ]},
        resolve: {    
            extensions: ['.vue']
        },
        plugins
    };
}